<?php
//worker 框架
require_once dirname(__DIR__) . '/vendor/workerman/workerman/Autoloader.php';

use Workerman\Worker;
use Workerman\Lib\Timer;

$env = isset($argv[3]) ? $argv[3] : '';
if (!in_array($env, ['test', 'beta', 'prod'])) {
    exit('invalid env param');
}
defined('YII_ENV') or define('YII_ENV', $env);

if (!in_array(YII_ENV, ['dev', 'prod', 'test', 'beta'])) {
    exit('invalid env param');
}

set_time_limit(0);

require(__DIR__ . '/../../protected/vendor/autoload.php');
require(__DIR__ . '/../../protected/vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../protected/boot/inject.php');
require(__DIR__ . '/../../protected/framework/bootstrap.php');
require(__DIR__ . '/../../protected/sdk/yii/security/Xcrypt.php');

$config = require(__DIR__ . '/../../protected/config/web.php');


$port = isset($argv[4]) ? $argv[4] : '2022';
// 心跳间隔25秒
define('HEARTBEAT_TIME', 25);
Worker::$logFile = '/tmp/workerman.log';
$worker = new Worker('websocket://0.0.0.0:' . $port);
//调用的数据接口
global $config;
$app = (new yii\web\Application($config));
global $app;
$popupNoticeService = Yii::$container->get('app\customerservicelogic\message\services\PopupNoticeService');
$worker->popupNoticeService = $popupNoticeService;

//$worker->count = 2;
$worker->onWorkerStart = function ($worker) {

    // 定时，每秒钟请求一次
    Timer::add(1, function () use ($worker) {
        $queryData = getData($worker->tenantCodeUserId, $worker);
        $timeNow = time();
        // 遍历当前进程所有的客户端连接，发送当前服务器的时间
        foreach ($worker->uidConnections as $key => $connection) {
            if (empty($connection->lastMessageTime)) {
                $connection->lastMessageTime = $timeNow;
                continue;
            }
            // 上次通讯时间间隔大于心跳间隔，则认为客户端已经下线，关闭连接
            if ($timeNow - $connection->lastMessageTime > HEARTBEAT_TIME) {
//                $connection->send('后端关闭|客户端心跳停止');
//                $connection->close();
//                unset($worker->uidConnections[$key]);
//                unset($worker->$tenantCodeUserId[$currentTenantCode][$key]);
//                continue;
            }
            $dataArr = explode(',', $key);
            $currentTenantCode = isset($dataArr[0]) ? $dataArr[0] : '';
            $currentUserId = isset($dataArr[1]) ? $dataArr[1] : '';
            if (isset($queryData[$currentTenantCode][$currentUserId])) {//有数据
                $currentMsg = $queryData[$currentTenantCode][$currentUserId];
                foreach ($currentMsg as $msg) {
                    $sendResult = $connection->send($msg);
                    if (!$sendResult) {
                        $connection->send('后端关闭|消息发送失败');
                        $connection->close();
                        unset($worker->uidConnections[$key]);
                        unset($worker->tenantCodeUserId[$currentTenantCode][$key]);
                        break;
                    }
                }
            }
        }
    });
};
$worker->onConnect = function ($connection) {
    // 有新的客户端连接时，连接数+1
    global $connection_count;
    ++$connection_count;
    $connection->send('连接消息|链接成功！');
};
$worker->uidConnections = array();
$worker->tenantCodeUserId = array();
$worker->onMessage = function ($connection, $data) use ($worker) {
    $dataArr = explode(',', $data);
    $tenantCode = isset($dataArr[0]) ? $dataArr[0] : '';
    $userId = isset($dataArr[1]) ? $dataArr[1] : '';
    $result = $worker->popupNoticeService->checkConnection($tenantCode, $userId);
    if ($result['success']) {//验证信息成功
        // 判断当前客户端是否已经验证,既是否设置了uid
        if (!isset($connection->uid)) {
            $connection->uid = $data;//保存uid到connection的映射，这样可以方便的通过uid查找connection，实现针对特定uid推送数据
            $worker->uidConnections[$connection->uid] = $connection;
        }
        //租户的用户链接信息
        $worker->tenantCodeUserId[$dataArr[0]][$data] = $dataArr[1];
        $connection->send($result['msg']);
    }
};
/**
 * 获取数据，组装返回格式[租户code][用户id][弹窗数据]
 * @param $tenantCodeUserId
 * @param $worker
 * @return array
 * @internal param $timeNow
 */
function getData($tenantCodeUserId, $worker)
{
    if (empty($tenantCodeUserId)) {
        return [];
    }
    $data = [];
    foreach ($tenantCodeUserId as $key => $value) {
        $currentTenantUser = array_values($value);
        $currentTenantUser = array_values(array_unique($currentTenantUser));
        $result = $worker->popupNoticeService->getNoticeMsg($key, $currentTenantUser);

        if ($result['success']) {
            $queryData = $result['msg'];
            foreach ($currentTenantUser as $vv) {
                $data[$key][$vv] = $queryData[$vv];
            }
        }
    }
    return $data;
}


if (!defined('GLOBAL_START')) {
    Worker::runAll();
}
